<?php

namespace App\Models;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;

/**
 * Date: 2018/1/25
 * @author George
 * @method static select(array $columns = ['*'])
 * @method static where($column, $operator = null, $value = null, $boolean = 'and')
 * @property $code
 * @property $permissions
 * @package App\Models
 */
class Role extends Model
{
    /**
     * 定义主键
     *
     * @var string
     * Date: 2018/1/25
     * @author George
     */
    protected $primaryKey = 'code';

    /**
     * 禁用主键自增
     *
     * @var bool
     * Date: 2018/1/25
     * @author George
     */
    public $incrementing = false;

    /**
     * 获取角色的权限
     *
     * Date: 2018/1/25
     * @author George
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function permissions()
    {
        return $this->belongsToMany(Permission::class, 'role_permission_pivot', 'role_code', 'permission_code', 'code');
    }

    /**
     * 获取角色关联的用户信息
     *
     * Date: 2018/1/26
     * @author George
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function users()
    {
        return $this->belongsToMany(User::class, 'user_role_pivot', 'role_code', 'user_id', 'code');
    }

    /**
     * 根据编码查找角色
     *
     * Date: 2018/1/25
     * @author George
     * @param string $code
     * @return Role
     */
    static public function findByCode(string $code): Role
    {
        $roleObj = Cache::rememberForever("roles:{$code}", function () use ($code) {
            return Role::where('code', $code)->first();
        });

        //判断是否是Role模型的实例
        if (!$roleObj instanceof Role) {
            $role = new Role();
            $role->code = $roleObj->code;
            return $role;
        }
        return $roleObj;
    }

    /**
     * 获取角色的权限信息
     *
     * Date: 2018/1/25
     * @author George
     * @return array
     */
    public function getPermissionsAttribute()
    {
        $permissions = [];
        //获取角色的权限编码
        $permissionCodes = $this->permissionCodes();
        //根据编码查询权限信息
        foreach ($permissionCodes as $permission) {
            $permissions[] = Cache::rememberForever("permissions:{$permission->permission_code}", function () use ($permission) {
                return DB::table('permissions')
                    ->select('code', 'name', 'permissiontable_id', 'permissiontable_type')
                    ->where('code', $permission->permission_code)
                    ->first();
            });
        }
        return $this->attributes['permissions'] = $permissions;
    }

    /**
     * 获取角色拥有权限的编码
     *
     * Date: 2018/1/25
     * @author George
     * @return mixed
     */
    public function permissionCodes()
    {
        return Cache::rememberForever("roles:{$this->code}:permissions", function () {
            return DB::table('role_permission_pivot')
                ->select('permission_code')
                ->where('role_code', $this->code)
                ->get();
        });
    }
}
